package es.ucm.fdi.xtremeaudio.modelo.beans;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * <ul>
 * <li><b>Proyecto:</b> XtremeAudio</li>
 * <li><b>Grupo:</b> 7 <i>(4&deg;B)</i></li>
 * <li><b>Asignatura:</b> Ingenier&iacute;a del Software</li>
 * <li><b>Curso:</b> 2010/2011</li>
 * <li><b>Centro:</b> Universidad Complutense de Madrid</li>
 * </ul>
 * 
 * La <b>Biblioteca</b> mantiene la informaci&oacute;n completa de la
 * aplicaci&oacute;n respecto a la reproducci&oacute;n, por medio de una serie
 * de canciones y de listas de reproducci&oacute;n asociadas con &eacute;stas.
 * Contiene una serie de &iacute;ndices para conocer en todo momento qu&eacute;
 * lista (o toda la biblioteca) muestra la lista y qu&eacute; canci&oacute;n (y
 * si pertenece a alguna lista) est&aacute; cargada actualmente.
 * 
 * @author &Aacute;lvaro G&oacute;mez Porris
 * @author Elena Hern&aacute;ndez Delgado
 * @author Mar&iacute;a Trinidad Mart&iacute;n Campos
 * @author Mois&eacute;s Mart&iacute;nez Montes
 * @author Mat&iacute;as Salinero Delgado
 * 
 * @version %I%, %G%
 * 
 * @since 1.0
 * 
 * @see Cancion
 * @see Playlist
 */
public class Biblioteca {

	/** Indica la biblioteca como lista actual o sonando. */
	public static int BIBLIOTECA = -1;

	/** Indica la &uacute;ltima b&uacute;squeda como lista actual o sonando. */
	public static int BUSQUEDA = -2;

	/** Indica alguna lista de reproducci&oacute;n como lista actual o sonando. */
	public static int PLAYLIST = 0;

	private ArrayList<Integer> busqueda = new ArrayList<Integer>();
	private ArrayList<Cancion> canciones = new ArrayList<Cancion>();
	private int indiceBusqueda = -1;
	private int indiceCancionActual = -1;
	private int indiceListaActual = BIBLIOTECA;
	private int indiceListaSonando = BIBLIOTECA;
	private ArrayList<Playlist> playlists = new ArrayList<Playlist>();

	/**
	 * Constructora por defecto. Inicializa la lista de canciones, de listas de
	 * reproduccion y de b&uacute;squedas (y sus repsectivos &iacute;ndices) a
	 * los valores por defecto. Establece la lista de canciones general como la
	 * lista actual mostrada y sonando.
	 */
	public Biblioteca() {}

	/**
	 * Asigna a una biblioteca existente una nueva lista de canciones y de
	 * listas de reproducci&oacute;n, junto con sus &iacute;ndices de
	 * reproducci&oacute;n actual visualizada en la vista.
	 * 
	 * @param canciones
	 *            Lista general de canciones.
	 * @param playlists
	 *            Lista de listas de reproducci&oacute;n.
	 * @param indiceCancionActual
	 *            &iacute;ndice de la canci&oacute;n actual de la biblioteca.
	 * @param indiceListaActual
	 *            &iacute;ndice de la lista actual de la biblioteca.
	 */
	public Biblioteca(ArrayList<Cancion> canciones,
			ArrayList<Playlist> playlists, int indiceCancionActual,
			int indiceListaActual) {
		this.canciones = canciones;
		this.playlists = playlists;
		this.indiceCancionActual = indiceCancionActual;
		this.indiceListaActual = indiceListaActual;
		busqueda = new ArrayList<Integer>();
		indiceBusqueda = -1;
		indiceListaSonando = BIBLIOTECA;
	}

	/**
	 * Indica si la biblioteca contiene canciones o no.
	 * 
	 * @return La vacuidad o no de la biblioteca.
	 */
	public boolean esVacia() {
		return (canciones.size() == 0);
	}

	/**
	 * Dada una ruta absoluta en forma de texto, indica si la cancui&oacute;n
	 * asociada la misma existe en la lista general de canciones.
	 * 
	 * @param path
	 *            El path de la canci&oacute;n a buscar.
	 * 
	 * @return La existencia o no de la canci&oacute;n dada por el path.
	 */
	public boolean existeCancion(String path) {
		if (!esVacia()) {
			Iterator<Cancion> it = canciones.iterator();
			while (it.hasNext()) {
				Cancion c = it.next();
				if (path.equalsIgnoreCase(c.getPath())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Accesora para lista asociada a la &uacute;ltima b&uacute;squeda.
	 * 
	 * @return La b&uacute;squeda.
	 */
	public ArrayList<Integer> getBusqueda() {
		return busqueda;
	}

	/**
	 * Accesora de la lista general de canciones.
	 * 
	 * @return La lista general de canciones.
	 * 
	 * @see Cancion
	 */
	public ArrayList<Cancion> getCanciones() {
		return canciones;
	}

	/**
	 * Obtiene la canci&oacute;n sonando (o cargada) actualmente en la
	 * biblioteca.
	 * 
	 * @return La canci&oacute;n.
	 * 
	 * @see Cancion
	 */
	public Cancion getCancionSonando() {
		int cancionLista = 0; // Indice de una cancion en una lista
		int cancionBiblio = 0; // Indice de una cancion en la biblioteca
		if (indiceListaSonando == BIBLIOTECA) {
			if (indiceCancionActual < canciones.size()) {
				return (canciones.get(indiceCancionActual));
			}
			return null;
		}
		if (indiceListaSonando == BUSQUEDA) {
			if (getIndiceBusqueda() < getBusqueda().size()) {
				cancionBiblio = getBusqueda().get(indiceBusqueda);
				return (canciones.get(cancionBiblio));
			}
		}
		if (indiceListaSonando < playlists.size()) {
			Playlist p = playlists.get(indiceListaSonando);
			cancionLista = p.getIndiceActual();
			if (cancionLista < p.getCanciones().size())
				cancionBiblio = p.getCanciones().get(cancionLista);
			return (canciones.get(cancionBiblio));
		}
		return null;
	}

	/**
	 * Obtiene el &iacute;ndice actual en la lista de la &uacute;ltima
	 * b&uacute;squeda.
	 * 
	 * @return El &iacute;ndice.
	 */
	public int getIndiceBusqueda() {
		return indiceBusqueda;
	}

	/**
	 * Obtiene el &iacute;ndice actual en la lista general de canciones.
	 * 
	 * @return El &iacute;ndice.
	 */
	public int getIndiceCancionActual() {
		return indiceCancionActual;
	}

	/**
	 * Obtiene el &iacute;ndice de la lista que se est&aacute; mostrando en la
	 * vista actualmente.
	 * 
	 * @return El &iacute;ndice.
	 */
	public int getIndiceListaActual() {
		return indiceListaActual;
	}

	/**
	 * Obtiene el &iacute;ndice de la lista de reproducci&oacute;n que
	 * est&aacute; sonando.
	 * 
	 * @return El &iacute;ndice.
	 */
	public int getIndiceListaSonando() {
		return indiceListaSonando;
	}

	/**
	 * Obtiene una lista de la lista de Playlists.
	 * 
	 * @param i
	 *            El &iacute;ndice de la lista a obtener.
	 * 
	 * @return La lista obtenida. Si no existe, devuelve <b>null</b>.
	 * 
	 * @see Playlist
	 */
	public Playlist getPlaylist(int i) {
		if ((i >= 0) && (i < playlists.size())) {
			return playlists.get(i);
		}
		return null;
	}

	/**
	 * Obtiene la lista de reproducci&oacute;n actual (visualizada). Si no es
	 * una Playlist, devuelve <b>null</b>.
	 * 
	 * @return La lista actual.
	 * 
	 * @see Playlist
	 */
	public Playlist getPlaylistActual() {
		if (indiceListaActual > BIBLIOTECA) {
			return playlists.get(indiceListaActual);
		}
		return null;
	}

	/**
	 * Obtiene la lista de listas de reproducci&oacute;n.
	 * 
	 * @return La lista de Playlists
	 * 
	 * @see Playlist
	 */
	public ArrayList<Playlist> getPlaylists() {
		return playlists;
	}

	/**
	 * Obtiene la lista de reproducci&oacute;n que suena actualmente, siempre
	 * que no sea la lista de b&uacute;squedas ni la biblioteca completa (en
	 * cuyo caso devuelve <b>null</b>).
	 * 
	 * @return La lista.
	 * 
	 * @see Playlist
	 */
	public Playlist getPlaylistSonando() {
		if (indiceListaSonando > BIBLIOTECA) {
			return playlists.get(indiceListaSonando);
		}
		return null;
	}

	/**
	 * Modificadora de lal ista de la &uacute;ltima b&uacute;squeda.
	 * 
	 * @param busqueda
	 *            La nueva lista de b&uacute;squeda.
	 */
	public void setBusqueda(ArrayList<Integer> busqueda) {
		this.busqueda = busqueda;
	}

	/**
	 * Modificadora de la lista general de canciones.
	 * 
	 * @param canciones
	 *            La nueva lista de canciones.
	 */
	public void setCanciones(ArrayList<Cancion> canciones) {
		this.canciones = canciones;
	}

	/**
	 * Modifica el &iacute;ndice actual en la lista de b&uacute;squedas.
	 * 
	 * @param indiceBusqueda
	 *            El nuevo &iacute;ndice.
	 */
	public void setIndiceBusqueda(int indiceBusqueda) {
		this.indiceBusqueda = indiceBusqueda;
	}

	/**
	 * Modifica el &iacute;ndice actual en la lista de canciones.
	 * 
	 * @param indiceCancionActual
	 *            El nuevo &iacute;ndice.
	 */
	public void setIndiceCancionActual(int indiceCancionActual) {
		this.indiceCancionActual = indiceCancionActual;
	}

	/**
	 * Modifica el &iacute;ndice actual en la lista visualizada (biblioteca,
	 * b&uacute;squedas o alguna de las listas de reproducci&oacute;n).
	 * 
	 * @param indiceListaActual
	 *            El nuevo &iacute;ndice.
	 */
	public void setIndiceListaActual(int indiceListaActual) {
		this.indiceListaActual = indiceListaActual;
	}

	/**
	 * Modifica el &iacute;ndice actual en la lista sonando (biblioteca,
	 * b&uacute;squedas o alguna de las listas de reproducci&oacute;n).
	 * 
	 * @param indiceListaSonando
	 *            El nuevo &iacute;ndice.
	 */
	public void setIndiceListaSonando(int indiceListaSonando) {
		this.indiceListaSonando = indiceListaSonando;
	}

	/**
	 * Modificadora de la lista de listas de reproducci&oacute;n.
	 * 
	 * @param playlists
	 *            La nueva lista de Playlists.
	 * 
	 * @see Playlist
	 */
	public void setPlaylists(ArrayList<Playlist> playlists) {
		this.playlists = playlists;
	}

}